﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Script.Serialization;

using System.Configuration;
namespace AccountFlow.Controllers
{
    public class FetchController : Controller
    {
        public ActionResult Index()
        {
            ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
            TwiterClient client = new TwiterClient();
            var htm = client.GetRandomeScore("RichardNatdell");
            ViewBag.Url = htm.Url;
            ViewBag.Json = htm.Json;

            return View();
        }

        public ActionResult Score()
        {


            ScoreSheet sheet = new ScoreSheet();
            FileLogger.Logger.IsSameFile = false;

            var p1 = new Personality()
            {
                Name = "Richard Nicholson"
            };
            var sp1 = new ScoreProvider()
            {
                AsOn = DateTime.Now.ToString(),
                Score = "",
                UserName = "RichardNatdell",
                ProviderName = "Klout"

            };
            var sp2 = new ScoreProvider()
            {
                AsOn = DateTime.Now.ToString(),
                Score = "",
                UserName = "",
                ProviderName = "LinkedIn"

            };
            var sp3 = new ScoreProvider()
            {
                AsOn = DateTime.Now.ToString(),
                Score = "",
                UserName = "",
                ProviderName = "Twitter"

            };
            p1.Providers.Add(sp1);
            p1.Providers.Add(sp2);
            p1.Providers.Add(sp3);


            var p10 = new Personality()
            {
                Name = "Vee Baker"
            };
            var sp10 = new ScoreProvider()
            {
                AsOn = DateTime.Now.ToString(),
                Score = "",
                UserName = "VeeBatDell",
                ProviderName = "Klout"

            };
            var sp20 = new ScoreProvider()
            {
                AsOn = DateTime.Now.ToString(),
                Score = "",
                UserName = "",
                ProviderName = "LinkedIn"

            };
            var sp30 = new ScoreProvider()
            {
                AsOn = DateTime.Now.ToString(),
                Score = "",
                UserName = "",
                ProviderName = "Twitter"

            };
            p10.Providers.Add(sp10);
            p10.Providers.Add(sp20);
            p10.Providers.Add(sp30);

            sheet.Personalies.Add(p1);
            sheet.Personalies.Add(p10);
            KloutClient klout = new KloutClient();
            try
            {
                foreach (var item in sheet.Personalies)
                {
                    foreach (var p in item.Providers)
                    {
                        if (p.ProviderName == "Klout")
                        {
                            p.Score = klout.GetRandomScore(p.UserName);
                            p.Data = klout.Buffer;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ViewBag.Error = ex;
            }
            ViewBag.Debug = klout.Buffer;
            return View(sheet);
        }

    }


    public static class RestToJsonObjectExtn
    {
        static WebClient client = new WebClient();
        static RestToJsonObjectExtn()
        {

        }
        public static dynamic ToJsonObject(this string url, string method = "GET")
        {
            string udata = client.DownloadString(url);
            dynamic userdata = Newtonsoft.Json.JsonConvert.DeserializeObject(udata);
            FileLogger.Logger.Write("URL=" + url);
            FileLogger.Logger.Write("JSON=" + udata);
            return userdata;
        }
        public static dynamic AsDynamic(this string josn)
        {
            dynamic userdata = Newtonsoft.Json.JsonConvert.DeserializeObject(josn);
            return userdata;
        }
    }

    public class FileLogger
    {
        string fex = @"call.txt";
        string basePath = "@c:\temp";
        bool isSameFile = false;

        public bool IsSameFile
        {
            set
            {
                isSameFile = value;
                fileName = (isSameFile) ? basePath + "\\" + fex : basePath + "\\" + "Log_" + DateTime.Now.Ticks + "_" + fex;
            }
        }
        string fileName;

        public string Prefix
        {
            set
            {
                fex = value;
                fileName = (isSameFile) ? basePath + "\\" + fex : basePath + "\\" + "Log_" + DateTime.Now.Ticks + "_" + fex;
            }
        }
        public FileLogger(string path = @"c:\temp", bool isSame = false)
        {
            basePath = path;
            IsSameFile = isSame;
        }
        public static FileLogger Logger = new FileLogger();
        public void Write(string message)
        {
            File.AppendAllText(fileName, message + Environment.NewLine);
        }
    }



    public class TwiterClient
    {
        string oauth_consumer_key = "0UK463JGnP7fHnDFzzWLJQ";
        string oauth_consumer_secret = "xAh9P4QWyoWvMOTF4P5O3OW5yx8lB3Cs4NvzDLYQ";

        string searchFormat = "https://api.twitter.com/1.1/search/tweets.json?q={0}";
        string timeLineFormat = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name={0}&include_rts={1}&exclude_replies={2}&count={3}";

        public HttpArgument GetRandomeScore(string screenName)
        {
            AuthenticateSettings twsettings = new AuthenticateSettings()
           {
               OAuthConsumerKey = "0UK463JGnP7fHnDFzzWLJQ",
               OAuthConsumerSecret = "xAh9P4QWyoWvMOTF4P5O3OW5yx8lB3Cs4NvzDLYQ",
               OAuthUrl = "https://api.twitter.com/oauth2/token"
           };
            OAuthTwitterWrapper tw = new OAuthTwitterWrapper(twsettings);
            var data = tw.Get(timeLineFormat, screenName, "1", "0", "5");
            return data;
        }
    }



    public class KloutClient
    {
        string token;
        string userUrlFormat = "http://api.klout.com/v2/identity.json/twitter?screenName={0}&key={1}";
        string topicUrlFormat = "http://api.klout.com/v2/user.json/{0}/topics?key={1}";
        string influenceUrlFormat = "http://api.klout.com/v2/user.json/{0}/influence?key={1}";
        string influenceTopicUrlFormat = "    http://api.klout.com/v2/user.json/{0}/influence?key={1}";
        string scoreUrlFormat = "http://api.klout.com/v2/user.json/{0}/score?key={1}";

        public string GetRandomScore(string userName)
        {
            string kloutUserUrl = string.Format(userUrlFormat, userName, token);
            dynamic userdata = Download(kloutUserUrl).AsDynamic();

            string kloutScoreUrl = string.Format(scoreUrlFormat, userdata.id, token);
            dynamic scoredata = Download(kloutScoreUrl).AsDynamic();

            string kloutTopicUrl = string.Format(topicUrlFormat, userdata.id, token);
            dynamic topicdata = Download(kloutTopicUrl).AsDynamic();

            string kloutInfluenceUrl = string.Format(influenceUrlFormat, userdata.id, token);
            dynamic influentdata = Download(kloutInfluenceUrl).AsDynamic();

            string kloutInfluenceTopicUrl = string.Format(influenceTopicUrlFormat, influentdata.myInfluencees[0].entity.id, token);
            dynamic influentTopicdata = Download(kloutInfluenceTopicUrl).AsDynamic();

            return scoredata.score;
        }
        Dictionary<string, string> buffer = new Dictionary<string, string>();

        public Dictionary<string, string> Buffer
        {
            get { return buffer; }
            set { buffer = value; }
        }

        public KloutClient(string accesstoken = "hu3kd2uk24wrkdnp227xaprc")
        {
            token = accesstoken;
        }
        public string Download(string url)
        {
            WebClient client = new WebClient();
            string udata = client.DownloadString(url);
            FileLogger.Logger.Write("URL=" + url);
            FileLogger.Logger.Write("JSON=" + udata);
            buffer.Add(url, udata);
            return udata;
        }

    }

    public class ScoreSheet
    {
        public ScoreSheet()
        {
            Personalies = new List<Personality>();
        }
        public List<Personality> Personalies { get; set; }
    }

    public class Personality
    {
        public string Name { get; set; }
        public List<ScoreProvider> Providers { get; set; }
        public Personality()
        {
            Providers = new List<ScoreProvider>();
        }
    }
    public class ScoreProvider
    {
        public string Score { get; set; }
        public string ProviderName { get; set; }
        public string AsOn { get; set; }
        public string UserName { get; set; }
        public object Data { get; set; }
    }

    public class OAuthTwitterWrapper
    {
        public AuthenticateSettings AuthenticateSettings { get; set; }


        /// <summary>
        /// This allows the authentications settings to be passed in
        /// </summary>
        /// <param name="authenticateSettings"></param>
        public OAuthTwitterWrapper(AuthenticateSettings authenticateSettings)
        {
            AuthenticateSettings = authenticateSettings;
        }

        public HttpArgument Get(string urlFormat, params string[] args)
        {
            string url = string.Format(urlFormat, args);
            var searchJson = string.Empty;
            Authenticate authenticate = new Authenticate();
            AuthResponse twitAuthResponse = authenticate.AuthenticateMe(AuthenticateSettings);

            var result = DownloadUrl(url, twitAuthResponse.TokenType, twitAuthResponse.AccessToken);
            result.UrlFormat = urlFormat;
            result.Json = Newtonsoft.Json.JsonConvert.DeserializeObject(result.Result);
            return result;
        }
        public HttpArgument DownloadUrl(string apiUrl, string tokenType, string accessToken)
        {
            var json = string.Empty;
            WebClient client = new WebClient();
            var timelineHeaderFormat = "{0} {1}";
            client.Headers.Add("Authorization",
                                        string.Format(timelineHeaderFormat, tokenType,
                                                      accessToken));
            json = client.DownloadString(apiUrl);
            return new HttpArgument() { Result = json, Url = apiUrl };
        }
    }
    public class HttpArgument
    {
        public string UrlFormat { get; set; }
        public string Url { get; set; }
        public string Result { get; set; }
        public dynamic Json { get; set; }
    }

    public class AuthResponse
    {

        [JsonProperty("token_type")]
        public string TokenType { get; set; }

        [JsonProperty("access_token")]
        public string AccessToken { get; set; }
    }
    public class AuthenticateSettings
    {
        public string OAuthUrl { get; set; }

        public string OAuthConsumerSecret { get; set; }

        public string OAuthConsumerKey { get; set; }
    }
    public class Authenticate
    {
        public AuthResponse AuthenticateMe(AuthenticateSettings authenticateSettings)
        {
            AuthResponse twitAuthResponse = null;
            // Do the Authenticate
            var authHeaderFormat = "Basic {0}";

            var authHeader = string.Format(authHeaderFormat,
                                           Convert.ToBase64String(
                                               Encoding.UTF8.GetBytes(Uri.EscapeDataString(authenticateSettings.OAuthConsumerKey) + ":" +

                                                                      Uri.EscapeDataString((authenticateSettings.OAuthConsumerSecret)))

                                               ));
            var postBody = "grant_type=client_credentials";
            HttpWebRequest authRequest = (HttpWebRequest)WebRequest.Create(authenticateSettings.OAuthUrl);

            authRequest.Headers.Add("Authorization", authHeader);
            authRequest.Method = "POST";
            authRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
            authRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
            using (Stream stream = authRequest.GetRequestStream())
            {
                byte[] content = ASCIIEncoding.ASCII.GetBytes(postBody);
                stream.Write(content, 0, content.Length);
            }
            authRequest.Headers.Add("Accept-Encoding", "gzip");
            WebResponse authResponse = authRequest.GetResponse();
            // deserialize into an object
            using (authResponse)
            {
                using (var reader = new StreamReader(authResponse.GetResponseStream()))
                {
                    JavaScriptSerializer js = new JavaScriptSerializer();
                    var objectText = reader.ReadToEnd();
                    twitAuthResponse = JsonConvert.DeserializeObject<AuthResponse>(objectText);
                }
            }

            return twitAuthResponse;
        }
    }
}
